package com.apkicon.parser;

import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
import java.util.Arrays;
import java.util.Comparator;

/**
 * Android密度解析器
 * 实现与PackageManager一致的密度匹配算法
 */
public class AndroidDensityResolver {
    
    /**
     * Android标准密度值（DPI）
     */
    private static final int DENSITY_LDPI = 120;
    private static final int DENSITY_MDPI = 160;
    private static final int DENSITY_HDPI = 240;
    private static final int DENSITY_XHDPI = 320;
    private static final int DENSITY_XXHDPI = 480;
    private static final int DENSITY_XXXHDPI = 640;
    
    /**
     * 密度名称到DPI的映射
     */
    private static final DensityInfo[] DENSITY_INFO = {
        new DensityInfo("ldpi", DENSITY_LDPI, 0.75f),
        new DensityInfo("mdpi", DENSITY_MDPI, 1.0f),
        new DensityInfo("hdpi", DENSITY_HDPI, 1.5f),
        new DensityInfo("xhdpi", DENSITY_XHDPI, 2.0f),
        new DensityInfo("xxhdpi", DENSITY_XXHDPI, 3.0f),
        new DensityInfo("xxxhdpi", DENSITY_XXXHDPI, 4.0f)
    };
    
    /**
     * 密度信息类
     */
    private static class DensityInfo {
        final String name;
        final int dpi;
        final float scale;
        
        DensityInfo(String name, int dpi, float scale) {
            this.name = name;
            this.dpi = dpi;
            this.scale = scale;
        }
    }
    
    /**
     * 按照Android PackageManager的算法查找最佳密度匹配的图标
     * @param apkFile APK文件
     * @param resourceName 资源名称
     * @param resourceType 资源类型（mipmap或drawable）
     * @param targetDpi 目标DPI
     * @return 最佳匹配的图标资源
     */
    public static IconResource findBestDensityMatch(ZipFile apkFile, String resourceName, String resourceType, int targetDpi) {
        System.out.println("🔍 按Android密度算法查找: " + resourceName + " (目标DPI: " + targetDpi + ")");
        
        // 1. 查找所有可用的密度变体
        DensityMatch[] matches = findAllDensityVariants(apkFile, resourceName, resourceType);
        
        if (matches.length == 0) {
            System.out.println("❌ 未找到任何密度变体");
            return null;
        }
        
        // 2. 按Android算法排序（最接近目标密度的优先）
        Arrays.sort(matches, new DensityComparator(targetDpi));
        
        // 3. 选择最佳匹配
        DensityMatch bestMatch = matches[0];
        System.out.println("✅ 最佳密度匹配: " + bestMatch.densityName + " (DPI: " + bestMatch.dpi + ", 差异: " + Math.abs(bestMatch.dpi - targetDpi) + ")");
        
        return bestMatch.iconResource;
    }
    
    /**
     * 查找所有密度变体
     */
    private static DensityMatch[] findAllDensityVariants(ZipFile apkFile, String resourceName, String resourceType) {
        java.util.List<DensityMatch> matches = new java.util.ArrayList<>();
        
        // 查找PNG图标
        for (DensityInfo densityInfo : DENSITY_INFO) {
            String pngPath = "res/" + resourceType + "-" + densityInfo.name + "/" + resourceName + ".png";
            ZipEntry entry = apkFile.getEntry(pngPath);
            if (entry != null) {
                IconResource iconResource = new IconResource(pngPath, "png", getSizeForDensity(densityInfo.name), densityInfo.name);
                matches.add(new DensityMatch(iconResource, densityInfo.name, densityInfo.dpi));
            }
        }
        
        // 查找WebP图标
        for (DensityInfo densityInfo : DENSITY_INFO) {
            String webpPath = "res/" + resourceType + "-" + densityInfo.name + "/" + resourceName + ".webp";
            ZipEntry entry = apkFile.getEntry(webpPath);
            if (entry != null) {
                IconResource iconResource = new IconResource(webpPath, "webp", getSizeForDensity(densityInfo.name), densityInfo.name);
                matches.add(new DensityMatch(iconResource, densityInfo.name, densityInfo.dpi));
            }
        }
        
        // 查找无密度标识的默认图标
        String defaultPngPath = "res/" + resourceType + "/" + resourceName + ".png";
        ZipEntry defaultPngEntry = apkFile.getEntry(defaultPngPath);
        if (defaultPngEntry != null) {
            IconResource iconResource = new IconResource(defaultPngPath, "png", 48, "mdpi");
            matches.add(new DensityMatch(iconResource, "mdpi", DENSITY_MDPI));
        }
        
        String defaultWebpPath = "res/" + resourceType + "/" + resourceName + ".webp";
        ZipEntry defaultWebpEntry = apkFile.getEntry(defaultWebpPath);
        if (defaultWebpEntry != null) {
            IconResource iconResource = new IconResource(defaultWebpPath, "webp", 48, "mdpi");
            matches.add(new DensityMatch(iconResource, "mdpi", DENSITY_MDPI));
        }
        
        return matches.toArray(new DensityMatch[0]);
    }
    
    /**
     * 密度匹配结果
     */
    private static class DensityMatch {
        final IconResource iconResource;
        final String densityName;
        final int dpi;
        
        DensityMatch(IconResource iconResource, String densityName, int dpi) {
            this.iconResource = iconResource;
            this.densityName = densityName;
            this.dpi = dpi;
        }
    }
    
    /**
     * 密度比较器 - 按照Android算法排序
     */
    private static class DensityComparator implements Comparator<DensityMatch> {
        private final int targetDpi;
        
        DensityComparator(int targetDpi) {
            this.targetDpi = targetDpi;
        }
        
        @Override
        public int compare(DensityMatch a, DensityMatch b) {
            // 1. 优先选择完全匹配的密度
            if (a.dpi == targetDpi && b.dpi != targetDpi) return -1;
            if (b.dpi == targetDpi && a.dpi != targetDpi) return 1;
            
            // 2. 选择最接近目标密度的
            int diffA = Math.abs(a.dpi - targetDpi);
            int diffB = Math.abs(b.dpi - targetDpi);
            
            if (diffA != diffB) {
                return Integer.compare(diffA, diffB);
            }
            
            // 3. 密度相同时，优先选择高密度（更清晰）
            return Integer.compare(b.dpi, a.dpi);
        }
    }
    
    /**
     * 根据密度名称获取对应的图标尺寸
     */
    private static int getSizeForDensity(String density) {
        switch (density) {
            case "ldpi": return 36;
            case "mdpi": return 48;
            case "hdpi": return 72;
            case "xhdpi": return 96;
            case "xxhdpi": return 144;
            case "xxxhdpi": return 192;
            default: return 48;
        }
    }
    
    /**
     * 获取密度名称对应的DPI值
     */
    public static int getDpiForDensity(String density) {
        for (DensityInfo info : DENSITY_INFO) {
            if (info.name.equals(density)) {
                return info.dpi;
            }
        }
        return DENSITY_MDPI; // 默认mdpi
    }
    
    /**
     * 获取密度名称对应的缩放因子
     */
    public static float getScaleForDensity(String density) {
        for (DensityInfo info : DENSITY_INFO) {
            if (info.name.equals(density)) {
                return info.scale;
            }
        }
        return 1.0f; // 默认mdpi
    }
}
